import { Callout, Sandpack } from '@/components'

# useSuspenseQueries

<Callout type='warning'>

**Deprecated in @suspensive/react-query**

This hook is now officially supported in TanStack Query v4.40.0+. Since TanStack Query has backported this interface, we are deprecating the backported version from @suspensive/react-query. Please migrate to the official TanStack Query interface:

```diff
- import { useSuspenseQueries } from '@suspensive/react-query'
+ import { useSuspenseQueries } from '@tanstack/react-query'
```

For more details, see [TanStack Query PR #9140](https://github.com/TanStack/query/pull/9140).

</Callout>

There is no isLoading or isError in the return type of this hook. This is because `<Suspense/>` and `<ErrorBoundary/>` guarantee the data of this hook. Also, in the options of this hook, suspense is set to true by default. You can use @tanstack/react-query's [useQueries](https://tanstack.com/query/v4/docs/react/reference/useQueries) for the new options you need.

```tsx /useSuspenseQueries/
import { useSuspenseQueries } from '@suspensive/react-query'

const Example = () => {
  const [query1, query2] = useSuspenseQueries({
    queries: [
      { queryKey: [1], queryFn },
      { queryKey: [2], queryFn },
    ],
  }) // suspense: true is the default.

  // No type narrowing required with isSuccess.
  query1.data // TData
  query2.data // TData
}
```

<Sandpack>

```tsx Post.tsx active
import { useSuspenseQueries } from '@suspensive/react-query'
import { getPost, getComments } from './api'

export const Post = ({ postId }: { postId: number }) => {
  const [postQuery, commentQuery] = useSuspenseQueries({
    queries: [
      { queryKey: ['posts', postId], queryFn: () => getPost(postId) },
      { queryKey: ['comments', postId], queryFn: () => getComments(postId) },
    ],
  })

  return (
    <div>
      <h1>{postQuery.data.title}</h1>
      <p>{postQuery.data.body}</p>
      <h2>Comments</h2>
      <ul>
        {commentQuery.data.map((comment) => (
          <li key={comment.id}>{comment.body}</li>
        ))}
      </ul>
    </div>
  )
}
```

```tsx Example.tsx
import { Suspense } from '@suspensive/react'
import { useState } from 'react'
import { Post } from './Post'

export const Example = () => {
  const [postId, setPostId] = useState(1)

  return (
    <div>
      <button
        onClick={() => setPostId((prev) => prev - 1)}
        disabled={postId === 1}
      >
        Previous Post
      </button>
      <button
        onClick={() => setPostId((prev) => prev + 1)}
        disabled={postId === 100}
      >
        Next Post
      </button>
      <Suspense fallback={<div>Loading...</div>}>
        <Post postId={postId} />
      </Suspense>
    </div>
  )
}
```

```tsx /api.ts
type Post = {
  userId: number
  id: number
  title: string
  body: string
}

export const getPost = async (id: number): Promise<Post> => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  )

  if (!response.ok) {
    throw new Error('An error occurred')
  }

  const data = await response.json()

  return data
}

type Comment = {
  postId: number
  id: number
  name: string
  email: string
  body: string
}

export const getComments = async (postId: number): Promise<Comment[]> => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/comments?postId=${postId}`
  )

  if (!response.ok) {
    throw new Error('An error occurred')
  }

  const data = await response.json()

  return data
}
```

</Sandpack>

### Motivation

You can use [useQueries](https://tanstack.com/query/v4/docs/react/reference/useQueries) with `<Suspense/>` and `<ErrorBoundary/>` by using the suspense option of @tanstack/react-query useQueries.

```tsx /useQueries/
import { useQueries } from '@tanstack/react-query'

const Example = () => {
  const [query1, query2] = useQueries({
    queries: [
      { queryKey: [1], queryFn, suspense: true },
      { queryKey: [2], queryFn, suspense: true },
    ],
  })

  query1.data // TData | undefined
  query2.data // TData | undefined

  if (query1.isSuccess) {
    query1.data // TData
  }
  if (query2.isSuccess) {
    query2.data // TData
  }
}
```

The return type of useQueries (query1.data, query2.data) will always be a success case thanks to this component's parents, `<Suspense/>` and `<ErrorBoundary/>`.
But @tanstack/react-query doesn't express this typologically.

That's why @suspensive/react-query provides **useSuspenseQueries**.

<Callout>

Focus on successful cases.

Now we can focus only on successful cases as fetching always succeeds inside our component.

</Callout>

### Version History

| Version  | Changes                                                                                                                                   |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `v3.0.0` | `networkMode` has been fixed to `'always'`. For more details, please refer to the [Migration to v3 guide](./migration/migrate-to-v3.mdx). |
